package com.bruan.aop;

import com.alibaba.fastjson.JSONObject;
import com.bruan.mapper.OperateLogMapper;
import com.bruan.pojo.OperateLog;
import com.bruan.utils.JwtUtils;
import io.jsonwebtoken.Claims;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.Arrays;

@Slf4j
@Component
@Aspect //切面类
public class OperateLogAspect {

    @Autowired
    private HttpServletRequest request;

    @Autowired
    private OperateLogMapper operateLogMapper;


    @Around("@annotation(com.bruan.anno.MyLog)") //绑定注解
    public Object OperateLog(@NotNull ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        //获取信息
        String jwt = request.getHeader("token");
        Claims claims = JwtUtils.parseJWT(jwt);
        Integer operateUser = (Integer) claims.get("id"); //创作人ID 从jwt中获取信息

        LocalDateTime operateTime = LocalDateTime.now(); //操作时间
        String className = proceedingJoinPoint.getTarget().getClass().getName(); //操作类名
        String methodName = proceedingJoinPoint.getSignature().getName(); //操作方法名
        String methodParams = Arrays.toString(proceedingJoinPoint.getArgs()); //操作方法参数

        long beginTime = System.currentTimeMillis();
        //调用原始目标方法运行
        Object result = proceedingJoinPoint.proceed();
        long endTime = System.currentTimeMillis();
        String returnValue = JSONObject.toJSONString(result); //操作方法返回值
        Long costTime = endTime - beginTime; //操作耗时

        //记录操作日志
        OperateLog operateLog = new OperateLog(
                null,
                operateUser=operateUser,operateTime=operateTime,
                className=className,methodName=methodName,
                methodParams=methodParams,returnValue=returnValue,
                costTime=costTime
        );

        operateLogMapper.insert(operateLog);
        log.info("AOP日志记录--{}--",operateLog);
        return result;
    }


}
